﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

namespace Mazin.SPGoogleMapPart
{
    [ToolboxItem(false)]
    public class MapEditorPart : EditorPart
    {
        private const string ItemHeader = "</div><div class=\"UserDottedLine\" style=\"width: 100%;\"/></td></tr><tr {1}><td><div class=\"UserSectionHead\"><label>{0}</label></div><div class=\"UserSectionBody\">";

        private CheckBox _httpsCheckbox;
        private CheckBox _clustererCheckbox;
        private CheckBox _panCheckbox;
        private CheckBox _zoomCheckbox;
        private CheckBox _mapTypeCheckbox;
        private CheckBox _streetviewCheckbox;
        private TextBox _camlQuery;
        private TextBox _centreLatitude;
        private TextBox _centreLongitude;
        private DropDownList _dataMode;
        private TextBox _descrColumName;
        private DropDownList _initialZoom;
        private TextBox _latColumnName;
        private TextBox _listUrl;
        private TextBox _lngColumnName;
        private TextBox _mapHeight;
        private DropDownList _mapType;
        private TextBox _mapWidth;
        private TextBox _titleColumnName;
        private TextBox _urlIdParamName;
        private TextBox _webUrl;
        private TextBox _iconUrl;

        private TextBox _apiKey;

        protected override void CreateChildControls()
        {

            LiteralControl control = new LiteralControl("<table style=\"width: 100%; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-collapse: collapse;\" border=\"0\" cellSpacing=\"0\"><tr><td><div class=\"UserSectionHead\"><label>HTTPS</label></div><div class=\"UserSectionBody\">");
            Controls.Add(control);
            _httpsCheckbox = new CheckBox();
            _httpsCheckbox.ToolTip = "Use HTTPS protocol to communicate with Google.";
            Controls.Add(_httpsCheckbox);

            control = new LiteralControl(string.Format(ItemHeader, "Google API key", string.Empty));
            Controls.Add(control);
            _apiKey = new TextBox { CssClass = "UserInput" };
            Controls.Add(_apiKey);

            control = new LiteralControl(string.Format(ItemHeader, "Group nearby points together", string.Empty));
            Controls.Add(control);
            _clustererCheckbox = new CheckBox();
            Controls.Add(_clustererCheckbox);

            control = new LiteralControl(string.Format(ItemHeader, "Display pan control", string.Empty));
            Controls.Add(control);
            _panCheckbox = new CheckBox();
            Controls.Add(_panCheckbox);

            control = new LiteralControl(string.Format(ItemHeader, "Display zoom control", string.Empty));
            Controls.Add(control);
            _zoomCheckbox = new CheckBox();
            Controls.Add(_zoomCheckbox);

            control = new LiteralControl(string.Format(ItemHeader, "Display map type control", string.Empty));
            Controls.Add(control);
            _mapTypeCheckbox = new CheckBox();
            Controls.Add(_mapTypeCheckbox);

            control = new LiteralControl(string.Format(ItemHeader, "Display StreetView control", string.Empty));
            Controls.Add(control);
            _streetviewCheckbox = new CheckBox();
            Controls.Add(_streetviewCheckbox);

            control = new LiteralControl(string.Format(ItemHeader, "Map Type", string.Empty));
            Controls.Add(control);
            _mapType = new DropDownList();
            _mapType.Items.Add(new ListItem("Major Streets On Satellite Images", "HYBRID"));
            _mapType.Items.Add(new ListItem("Normal Street Map", "ROADMAP"));
            _mapType.Items.Add(new ListItem("Satellite Images", "SATELLITE"));
            _mapType.Items.Add(new ListItem("Maps with physical features such as terrain and vegetation", "TERRAIN"));
            Controls.Add(_mapType);

            control = new LiteralControl(string.Format(ItemHeader, "Centre Langitude", string.Empty));
            Controls.Add(control);
            _centreLatitude = new TextBox();
            _centreLatitude.CssClass = "UserInput";
            _centreLatitude.Attributes.Add("onchange", "ValidateDouble(this);");
            Controls.Add(_centreLatitude);

            control = new LiteralControl(string.Format(ItemHeader, "Centre Longitude", string.Empty));
            Controls.Add(control);
            _centreLongitude = new TextBox {CssClass = "UserInput"};
            _centreLongitude.Attributes.Add("onchange", "ValidateDouble(this);");
            Controls.Add(_centreLongitude);

            control = new LiteralControl(string.Format(ItemHeader, "Map Height", string.Empty));
            Controls.Add(control);
            _mapHeight = new TextBox();
            _mapHeight.CssClass = "UserInput";
            _mapHeight.Attributes.Add("onchange", "ValidateInt(this);");
            Controls.Add(_mapHeight);

            control = new LiteralControl(string.Format(ItemHeader, "Map Width", string.Empty));
            Controls.Add(control);
            _mapWidth = new TextBox();
            _mapWidth.CssClass = "UserInput";
            _mapWidth.Attributes.Add("onchange", "ValidateInt(this);");
            Controls.Add(_mapWidth);

            control = new LiteralControl(string.Format(ItemHeader, "Initial Zoom", string.Empty));
            Controls.Add(control);
            _initialZoom = new DropDownList();
            _initialZoom.Items.Add(new ListItem("17 - Street Level", "17"));
            _initialZoom.Items.Add(new ListItem("16", "16"));
            _initialZoom.Items.Add(new ListItem("15", "15"));
            _initialZoom.Items.Add(new ListItem("14 - Town Level", "14"));
            _initialZoom.Items.Add(new ListItem("13", "13"));
            _initialZoom.Items.Add(new ListItem("12", "12"));
            _initialZoom.Items.Add(new ListItem("11 - City Level", "11"));
            _initialZoom.Items.Add(new ListItem("10", "10"));
            _initialZoom.Items.Add(new ListItem("9", "9"));
            _initialZoom.Items.Add(new ListItem("8 - Region Level", "8"));
            _initialZoom.Items.Add(new ListItem("7", "7"));
            _initialZoom.Items.Add(new ListItem("6", "6"));
            _initialZoom.Items.Add(new ListItem("5 - Country Level", "5"));
            _initialZoom.Items.Add(new ListItem("4", "4"));
            _initialZoom.Items.Add(new ListItem("3", "3"));
            _initialZoom.Items.Add(new ListItem("2", "2"));
            _initialZoom.Items.Add(new ListItem("1 - World Level", "1"));
            Controls.Add(_initialZoom);

            control = new LiteralControl(string.Format(ItemHeader, "Icon URL / Icon URL column name", string.Empty));
            Controls.Add(control);
            _iconUrl = new TextBox();
            _iconUrl.CssClass = "UserInput";
            _iconUrl.ToolTip = "Enter the valid URL (absolute or relative) for all points or enter the name of list column containing the URL of each item.";
            Controls.Add(_iconUrl);

            control = new LiteralControl(string.Format(ItemHeader, "Data Mode - how to get data to display", string.Empty));
            Controls.Add(control);
            _dataMode = new DropDownList();
            _dataMode.Items.Add(new ListItem("List & Query", "1"));
            _dataMode.Items.Add(new ListItem("List & Item ID", "2"));
            _dataMode.Items.Add(new ListItem("Full URL params", "3"));
            _dataMode.Attributes.Add("onchange", "DataModeChanged(this)");
            _dataMode.ToolTip = "Specify how the webpart gets data you want to display on map.";
            Controls.Add(_dataMode);

            control = new LiteralControl(@"<br>
<b>List & Query</b> - webpart gets items fulfilling CAML Query from the list specified by Web and List URL.<br>
<b>List & Item ID</b> - webpart gets single item from the list specified by Web and List URL. ID of this item is taken from URL parameter Item ID Parameter Name.<br>
<b>Full URL params</b>");
            Controls.Add(control);

            control = new LiteralControl(string.Format(ItemHeader, "Web URL", "id=\"list\""));
            Controls.Add(control);
            _webUrl = new TextBox {CssClass = "UserInput"};
            Controls.Add(_webUrl);
            
            control =
                new LiteralControl(
                    string.Format(
                        "</div><br/><div class=\"UserSectionHead\"><label>{0}</label></div><div class=\"UserSectionBody\">",
                        "List URL"));
            Controls.Add(control);
            _listUrl = new TextBox();
            _listUrl.CssClass = "UserInput";
            Controls.Add(_listUrl);
            control =
                new LiteralControl(
                    string.Format("&nbsp;<input type=\"button\" value=\"{0}\" onclick=\"portal_openModalDialog()\" />", "Browse..."));
            Controls.Add(control);

            control = new LiteralControl(string.Format(ItemHeader, "CAML Query", "id=\"query\""));
            Controls.Add(control);
            _camlQuery = new TextBox();
            _camlQuery.CssClass = "UserInput";
            Controls.Add(_camlQuery);

            control = new LiteralControl(string.Format(ItemHeader, "Item ID URL Parameter Name", "id=\"itemId\""));
            Controls.Add(control);
            _urlIdParamName = new TextBox();
            _urlIdParamName.CssClass = "UserInput";
            _urlIdParamName.ToolTip = "Specify the name of URL paramater containing the ID of item you want to display on map.";
            Controls.Add(_urlIdParamName);

            control = new LiteralControl(string.Format(ItemHeader, "Title Column Name", string.Empty));
            Controls.Add(control);
            _titleColumnName = new TextBox();
            _titleColumnName.CssClass = "UserInput";
            Controls.Add(_titleColumnName);

            control = new LiteralControl(string.Format(ItemHeader, "Description column name", string.Empty));
            Controls.Add(control);
            _descrColumName = new TextBox();
            _descrColumName.CssClass = "UserInput";
            Controls.Add(_descrColumName);

            control = new LiteralControl(string.Format(ItemHeader, "Latitude column name", string.Empty));
            Controls.Add(control);
            _latColumnName = new TextBox();
            _latColumnName.CssClass = "UserInput";
            Controls.Add(_latColumnName);

            control = new LiteralControl(string.Format(ItemHeader, "Longitude column name", string.Empty));
            Controls.Add(control);
            _lngColumnName = new TextBox();
            _lngColumnName.CssClass = "UserInput";
            Controls.Add(_lngColumnName);

            control =
                new LiteralControl(
                    String.Format(
                        "<script type=\"text/javascript\" src=\"/_layouts/1033/pickertreedialog.js\"></script><script type=\"text/javascript\">function ValidateInt(control) {{var tmp = parseInt(control.value);return !isNaN(tmp);}}function ValidateDouble(control) {{var tmp = parseFloat(control.value);return !isNaN(tmp);}}function DataModeChanged(control) {{if (control.value == \"0\" || control.value == \"3\") {{document.getElementById(\"list\").style.display = 'none';document.getElementById(\"itemId\").style.display = 'none';document.getElementById(\"query\").style.display = 'none';return;}}if (control.value == \"1\") {{document.getElementById(\"list\").style.display = '';document.getElementById(\"query\").style.display = '';document.getElementById(\"itemId\").style.display = 'none';return;}}if (control.value == \"2\") {{document.getElementById(\"list\").style.display = '';document.getElementById(\"itemId\").style.display = '';document.getElementById(\"query\").style.display = 'none';return;}}}}" +
                        "function portal_openModalDialog() {{ var callback = function (dest) {{ if (dest != null && dest != undefined && dest[3] != null) {{ document.getElementById('{0}').value = dest[1];document.getElementById('{1}').value = dest[3]; }} }};" +
                        "SP.SOD.executeFunc('pickertreedialog.js', 'LaunchPickerTreeDialogSelectUrl', function () {{ LaunchPickerTreeDialogSelectUrl('CbqPickerSelectListTitle', 'CbqPickerSelectListText', 'websListsFolders', '', '', '', '', '', \"/_layouts/15/images/smt_icon.gif?rev=32\", '', callback, 'true', '');}});" +
                        "}} DataModeChanged(document.getElementById('{2}'))</script>", _webUrl.ClientID, _listUrl.ClientID, _dataMode.ClientID));
            Controls.Add(control);
        }

        public override bool ApplyChanges()
        {
            //from editorpart tu webpart properties
            try
            {
                var webpart = (VisualWebPart) WebPartToEdit;
                webpart.ZoomLevel = int.Parse(_initialZoom.Text);
                webpart.MapWidth = int.Parse(_mapWidth.Text);
                webpart.MapHeight = int.Parse(_mapHeight.Text);
                webpart.WebUrl = _webUrl.Text;
                webpart.TitleColumn = _titleColumnName.Text;
                webpart.MapType = _mapType.Text;
                webpart.LongitudeColumn = _lngColumnName.Text;
                webpart.LatitudeColumn = _latColumnName.Text;
                webpart.ListUrl = _listUrl.Text;
                webpart.ListQuery = _camlQuery.Text;
                webpart.ListItemIdParamName = _urlIdParamName.Text;
                webpart.CentreLongitude = double.Parse(_centreLongitude.Text);
                webpart.CentreLatitude = double.Parse(_centreLatitude.Text);
                webpart.DescriptionColumn = _descrColumName.Text;
                webpart.DataMode = int.Parse(_dataMode.SelectedValue);
                webpart.Https = _httpsCheckbox.Checked;
                webpart.PanControl = _panCheckbox.Checked;
                webpart.ZoomControl = _zoomCheckbox.Checked;
                webpart.MapTypeControl = _mapTypeCheckbox.Checked;
                webpart.StreetViewControl = _streetviewCheckbox.Checked;
                webpart.UseClusterer = _clustererCheckbox.Checked;
                webpart.IconUrl = _iconUrl.Text;
                webpart.ApiKey = _apiKey.Text;

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public override void SyncChanges()
        {
            //from webpart to editpart
            var webpart = (VisualWebPart) WebPartToEdit;
            EnsureChildControls();

            _initialZoom.Text = webpart.ZoomLevel.ToString(CultureInfo.InvariantCulture);
            _mapWidth.Text = webpart.MapWidth.ToString(CultureInfo.InvariantCulture);
            _mapHeight.Text = webpart.MapHeight.ToString(CultureInfo.InvariantCulture);
            _webUrl.Text = webpart.WebUrl;
            _titleColumnName.Text = webpart.TitleColumn;
            _mapType.SelectedValue = webpart.MapType;
            _lngColumnName.Text = webpart.LongitudeColumn;
            _latColumnName.Text = webpart.LatitudeColumn;
            _listUrl.Text = webpart.ListUrl;
            _camlQuery.Text = webpart.ListQuery;
            _urlIdParamName.Text = webpart.ListItemIdParamName;
            _centreLongitude.Text = webpart.CentreLongitude.ToString(CultureInfo.InvariantCulture);
            _centreLatitude.Text = webpart.CentreLatitude.ToString(CultureInfo.InvariantCulture);
            _descrColumName.Text = webpart.DescriptionColumn;
            _dataMode.SelectedValue = webpart.DataMode.ToString(CultureInfo.InvariantCulture);
            _httpsCheckbox.Checked = webpart.Https;

            _panCheckbox.Checked = webpart.PanControl;
            _zoomCheckbox.Checked = webpart.ZoomControl;
            _mapTypeCheckbox.Checked = webpart.MapTypeControl;
            _streetviewCheckbox.Checked = webpart.StreetViewControl;
            _clustererCheckbox.Checked = webpart.UseClusterer;

            _iconUrl.Text = webpart.IconUrl;

            _apiKey.Text = webpart.ApiKey;
        }
    }
}
